package ade.prime.activity;

import ade.prime.activity.parameters.ParameterNames;
import ade.prime.activity.parameters.ParameterType;
import ade.prime.activity.parameters.Parameters;
import ade.prime.activity.parameters.ScheduleName;
import ade.prime.activity.parameters.SchedulePeriod;
import ade.prime.activity.parameters.ScheduleProject;
import ade.prime.activity.parameters.ScheduleResource;
import ade.prime.activity.parameters.ScheduleRessourceTitle;
import ade.prime.model.AdeWebOptions;
import ade.prime.model.Project;
import ade.prime.model.Resource;
import ade.prime.model.Schedule;
import android.content.Intent;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;

public class CreateSchedule extends AdeWebActivity
implements ParameterNames {
	
//	@SuppressWarnings("hiding")
//	private static final String TAG = CreateSchedule.class.getSimpleName() ;

	/**
	 * Composant contenant les différents champs du formulaire.
	 */
	private LinearLayout fields ;

	/**
	 * Différents champs affichés dans le formulaire.
	 */
	protected Parameters params ;

	/**
	 * L'index d'insersion pour les nouvelles ressources.
	 */
	protected int newResIndex ;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState) ;

		this.setTheme(AdeWebOptions.getTheme(this)) ;
		this.init() ;
		this.initListeners() ;
	}// onCreate(Bundle)

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		Intent helpIntent = new Intent(this, UserManual.class) ;
		menu.add(R.string.ActionBar_help)
		.setIcon(R.drawable.ic_action_help_holo_light)
		.setIntent(helpIntent)
		.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER) ;

		return super.onCreateOptionsMenu(menu) ;
	}// onCreateOptionsMenu(Menu)

	/**
	 * Initialise les champs avec les valeurs données pour l'affichage graphique.
	 * 
	 * @param 	name
	 * 			Initial values for the schedule name
	 * 
	 * @param 	resources
	 * 			Initial values for the resources
	 * 
	 * @param 	period
	 * 			Initial value for the period
	 * 
	 * @param 	projectId
	 * 			Initial value for the selected project
	 */
	public void init(String name, String resources, Integer period, Project project) {
		LayoutInflater inflater = LayoutInflater.from(this) ;
		// Initializing the fields --------------------------------------------------
		this.params = new Parameters() ;
		this.params.add(new ScheduleName(inflater,name)) ;
		this.params.add(new ScheduleRessourceTitle(inflater, this)) ;
		this.newResIndex = this.params.size() ;
		for(String ressource : resources.split("\\|")) { //$NON-NLS-1$
			this.params.add(new ScheduleResource(inflater, ressource, this)) ;
			this.newResIndex++ ;
		}// for
		//TODO Add separator like ScheduleRessourceTitle for the end of the resources
		this.params.add(new SchedulePeriod(inflater, period)) ;
		this.params.add(new ScheduleProject(inflater, project)) ;

		// Building the view layout ------------------------------------------------
		this.setContentView(R.layout.create_schedule) ;
		this.fields = (LinearLayout) this.findViewById(R.id.create_schedule_fields) ;
		this.fields.setOrientation(LinearLayout.VERTICAL) ;
		for(ParameterType param : this.params) {
			this.fields.addView(param.getView(null, null)) ;
		}// for
	}// init(String, String, String, String)

	/**
	 * Ajoute une nouvelle ressource à la vue.
	 */
	public void addResource () {
		LayoutInflater inflater = LayoutInflater.from(this) ;
		ParameterType newRes = new ScheduleResource(inflater, "", this) ; //$NON-NLS-1$
		this.params.add(this.newResIndex, newRes) ;
		this.fields.addView(newRes.getView(null,  null), this.newResIndex) ;
		this.newResIndex++ ;
	}// addResource()

	/**
	 * Supprime un ressource de la vue.
	 * 
	 * @param 	removedView
	 * 			view which should well be removed
	 * 
	 * @param 	id
	 * 			id of the view which should be removed
	 * 
	 * @see		ScheduleResource
	 */
	public void removeResource (View removedView, int id) {
		this.fields.removeView(removedView) ;
		this.params.removeResource(id) ;
		this.newResIndex-- ;
	}// removeResource()

	/**
	 * Initialise la vue avec les valeurs par défaut.
	 */
	public void init() {
		this.init("", "", null, null) ; //$NON-NLS-1$ //$NON-NLS-2$
	}// init()

	/**
	 * Attache les écouteurs des boutons "enregistrer" et "annuler".
	 */
	protected void initListeners() {	
		final Button saveButton   = (Button) this.findViewById(R.id.saveSchedule) ;
		final Button cancelButton = (Button) this.findViewById(R.id.cancelSchedule) ;
		saveButton.setOnClickListener(this.getSaveListener()) ;
		cancelButton.setOnClickListener(new CancelListener(this)) ;
	}// initListeners()

	/**
	 * Retourne la 1ere instance trouvée de {@code ParamaterType} avec l'ID donné.
	 * 
	 * @param 	id
	 * 			id of the search {@code ParameterType}
	 * 
	 * @return	First instance of {@code ParamaterType} found with the given id
	 */
	public ParameterType getById(String id) {
		return this.params.getById(id) ;
	}// getById(String)

	/**
	 * Retourne toutes les instances trouvées de {@code ParamaterType} avec l'ID donné.
	 * 
	 * @param 	id
	 * 			id of the search {@code ParameterType}
	 * 
	 * @return	Array containing all the instance of {@code ParamaterType} found 
	 * 			with the given id
	 */
	public Parameters getAllById(String id) {
		return this.params.getAllById(id) ;
	}// getAllById(String)

	/**
	 * Retourne le composant graphique contenant les champs du formulaire.
	 * 
	 * @return	
	 */
	public LinearLayout getFields() {
		return this.fields ;
	}// getFields()

	/**
	 * OnClickListener pour le bouton "enregistrer".
	 * 
	 *  <p>Retrouve la donnée depuis le formulaire et insère l'emploi du temps dans la base de données si possible.
	 * 
	 * @author  Zanette Sébastien, Andrianjafintrimo Victor
	 */
	class SaveListener extends Object implements OnClickListener {
		
		private final String mTAG = SaveListener.class.getSimpleName() ;

		/**
		 * Vue contenant le composant attaché à l'écouteur.
		 */
		protected CreateSchedule container ;

		/**
		 * Constructeur. 
		 * 
		 * @param 	container
		 * 			View containing the component attached to this listener
		 */
		public SaveListener(CreateSchedule container) {
			super() ;
			this.container = container ;
		}// SaveListener(CreateSchedule)

		/**
		 * Définition des actions du clique sur le composant attaché.
		 * 
		 * @param	actualView
		 * 			view of the component who has received a click event
		 */
		@Override
		public void onClick(View view) {
			LinearLayout actualView = this.container.getFields() ;
			// Retrieve form data
			String name = this.container.getById(ScheduleName.FIELD_ID)
					.getValue(actualView).toString() ;
			int nResources = this.container.newResIndex - 2 ;
			Resource[] resources = new Resource[nResources] ;
			for(int r=0; r < nResources; ++r) {
				String resource = (String) this.container.params.get(r+2)
						.getValue(actualView.getChildAt(r+2)) ;
				resources[r] = new Resource(resource) ;
			}// for
			int period = ((Integer) this.container.getById(PARAMETER_PERIOD)
					.getValue(actualView)).intValue() ;
			Project project = (Project) this.container.getById(ScheduleProject.FIELD_ID)
					.getValue(actualView) ;
			
			try {
//				Log.d(TAG, "Creating schedule, values:") ;
//				Log.d(TAG, "-- name:" + name) ;
//				Log.d(TAG, "-- resources:" + Arrays.toString(resources)) ;
//				Log.d(TAG, "-- period:" + period) ;
//				Log.d(TAG, "-- project:" + project) ;
				Schedule result = this.container.serviceApi
					.createSchedule(name, resources, period, project) ;
//				Log.d(TAG, "Schedule: " + result) ;
				if (result != null) {
					this.container.onBackPressed() ;
				} else {
					Toast.makeText(this.container, 
							"Echec de la création de l'emploi du temps.",  //$NON-NLS-1$
							Toast.LENGTH_SHORT).show() ;
				}// if
			} catch (RemoteException re) {
				// TODO Handle exception
				Log.d(this.mTAG, "Failed to create schedule", re) ; //$NON-NLS-1$
			}// try
		}// onClick(View) 

	}// class SaveListener

	/**
	 * OnClickListener pour le bouton "annuler".
	 * 
	 * <p>Retour à la vue précédente.
	 * 
	 * @author ZANETTE Sébastien
	 */
	class CancelListener implements OnClickListener {

		/**
		 * Vue contenant le composant attaché à l'écouteur.
		 */
		protected CreateSchedule container ;

		/**
		 * Constructeur. 
		 * 
		 * @param 	container
		 * 			View containing the component attached to this listener
		 */
		public CancelListener(CreateSchedule container) {
			super() ;
			this.container = container ;
		}// CancelListener(CreateSchedule)

		/**
		 * Définition des action du clique sur le composant attaché.
		 * 
		 * @param	actualView
		 * 			view of the component who has received a click event
		 */
		@Override
		public void onClick(View actuelView) {
			this.container.onBackPressed() ;
		}// onClick(View)

	}// class CancelListener

	/**
	 * Retourne une instance de {@code OnClickListener} pour l'enregistrement.
	 * 
	 * @return	instance de {@code OnClickListener} pour l'enregistrement
	 */
	protected OnClickListener getSaveListener() {
		return new SaveListener(this) ;
	}// getSaveListener()

	/**
	 * Construit une chaine de caractères contenant les ressources séparées par '|'.
	 * @return les ressources séparées par '|'.
	 */
	protected String getScheduleResources () {
		StringBuffer resString = new StringBuffer() ;
		for(int resId=2; resId < this.newResIndex; ++resId) {
			View resView = this.fields.getChildAt(resId) ;
			String value = (String) this.params.get(resId).getValue(resView) ;
			if (value.length() > 0) {
				resString.append("|") ; //$NON-NLS-1$
				resString.append(value) ;
			}// if
		}// for
		if (resString.length() == 0) {
			return "" ; //$NON-NLS-1$
		}// if
		return resString.substring(1) ;
	}// getResources()

//	/**
//	 * Vérifie si l'appareil est connecté à Internet
//	 * @return vrai si l'appareil est connecté à Internet, faux sinon
//	 */   
//	protected boolean isNetworkAvailable() {
//		ConnectivityManager connectivityManager = 
//				(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE) ;
//		NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo() ;
//		boolean networkAvailable = false ;
//		if (activeNetworkInfo != null) {
//			networkAvailable = activeNetworkInfo.isConnected() ;
//		}// if		
//		return networkAvailable ;
//	}

}// class CreateSchedule